{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "var a [3]int                    // 定义长度为 3 的 int 型数组, 元素全部为 0\n",
    "var b = [...]int{1, 2, 3}       // 定义长度为 3 的 int 型数组, 元素为 1, 2, 3\n",
    "var c = [...]int{2: 3, 1: 2}    // 定义长度为 3 的 int 型数组, 元素为 0, 2, 3\n",
    "var d = [...]int{1, 2, 4: 5, 6} // 定义长度为 6 的 int 型数组, 元素为 1, 2, 0, 0, 5, 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2 <nil>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import \"fmt\"\n",
    "fmt.Println(b[0])\n",
    "var e = &b\n",
    "fmt.Println(e[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1\n",
      "1 2\n",
      "2 3\n"
     ]
    }
   ],
   "source": [
    "for i, v := range b {\n",
    "\tfmt.Println(i, v)\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a[0]: 1\n",
      "a[1]: 2\n",
      "a[2]: 3\n"
     ]
    }
   ],
   "source": [
    "for i := range b {\n",
    "\tfmt.Printf(\"a[%d]: %d\\n\", i, b[i])\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a[0]: 1\n",
      "a[1]: 2\n",
      "a[2]: 3\n"
     ]
    }
   ],
   "source": [
    "for i := 0; i < len(b); i++ {\n",
    "\tfmt.Printf(\"a[%d]: %d\\n\", i, b[i])\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "hello\n",
      "hello\n",
      "hello\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "var times [5][0]int // 其中 times 对应一个 [5][0]int 类型的数组，虽然第一维数组有长度，但是数组的元素 [0]int 大小是 0，因此整个数组占用的内存大小依然是 0。\n",
    "for range times {\n",
    "\tfmt.Println(\"hello\")\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b: [3]int\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "10 <nil>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fmt.Printf(\"b: %T\\n\", b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b: [3]int{1, 2, 3}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "19 <nil>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fmt.Printf(\"b: %#v\\n\", b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "6 <nil>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s := \"hello, world\"\n",
    "hello := s[:5]\n",
    "fmt.Println(hello)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "37 <nil>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fmt.Printf(\"%#v\\n\", []byte(\"hello\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "�helloabc\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "10 <nil>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fmt.Println(\"\\x68\\x65\\x6c\\x6c\\x6f\")\n",
    "fmt.Println(\"\\xe4\\x68\\x65\\x6c\\x6c\\x6fabc\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# slice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1 2 3]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var (\n",
    "    a []int               // nil 切片, 和 nil 相等, 一般用来表示一个不存在的切片\n",
    "    b = []int{}           // 空切片, 和 nil 不相等, 一般用来表示一个空的集合\n",
    "    c = []int{1, 2, 3}    // 有 3 个元素的切片, len 和 cap 都为 3\n",
    "    d = c[:2]             // 有 2 个元素的切片, len 为 2, cap 为 3\n",
    "    e = c[0:2:cap(c)]     // 有 2 个元素的切片, len 为 2, cap 为 3\n",
    "    f = c[:0]             // 有 0 个元素的切片, len 为 0, cap 为 3\n",
    "    g = make([]int, 3)    // 有 3 个元素的切片, len 和 cap 都为 3\n",
    "    h = make([]int, 2, 3) // 有 2 个元素的切片, len 为 2, cap 为 3\n",
    "    i = make([]int, 0, 3) // 有 0 个元素的切片, len 为 0, cap 为 3\n",
    ")\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a[0]: 1\n",
      "a[1]: 2\n",
      "a[2]: 3\n"
     ]
    }
   ],
   "source": [
    "for i := range c {\n",
    "\tfmt.Printf(\"a[%d]: %d\\n\", i, c[i])\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1 2 3 4 5]"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = append(a, 1)\n",
    "a = append(a, 2, 3)\n",
    "a = append(a, []int{4, 5}...)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0 0 1 2 3 4 5]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = append([]int{0}, a...)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "ename": "ERROR",
     "evalue": "repl.go:1:13: first argument to append must be slice; have <untyped.Lit>",
     "output_type": "error",
     "traceback": [
      "repl.go:1:13: first argument to append must be slice; have <untyped.Lit>"
     ]
    }
   ],
   "source": [
    "a = append(-1, a...)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0 0 1 2 3 1 2 3 4 5]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = append(a[:2], append([]int{1,2,3}, a[2:]...)...)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0 9 0 1 2 3 1 2 3 4]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "copy(a[2:], a[1:])\n",
    "a[1] = 9\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1 2]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = []int{1, 2, 3}\n",
    "a = a[:len(a)-1]   // 删除尾部 1 个元素\n",
    "// a = a[:len(a)-N]   // 删除尾部 N 个元素\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2 3]"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = []int{1, 2, 3}\n",
    "a = a[1:] // 删除开头 1 个元素\n",
    "// a = a[N:?] // 删除开头 N 个元素\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "ename": "ERROR",
     "evalue": "interface conversion: interface {} is func(*fast.Env), not func(*fast.Env) int",
     "output_type": "error",
     "traceback": [
      "interface conversion: interface {} is func(*fast.Env), not func(*fast.Env) int"
     ]
    }
   ],
   "source": [
    "a = []int{1, 2, 3}\n",
    "a = a[:copy(a, a[1:])] // 删除开头 1 个元素\n",
    "// a = a[:copy(a, a[N:])] // 删除开头 N 个元素\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "ename": "ERROR",
     "evalue": "repl.go:2:10: undefined \"ioutil\" in ioutil.ReadFile <*ast.SelectorExpr>",
     "output_type": "error",
     "traceback": [
      "repl.go:2:10: undefined \"ioutil\" in ioutil.ReadFile <*ast.SelectorExpr>"
     ]
    }
   ],
   "source": [
    "func FindPhoneNumber(filename string) []byte {\n",
    "\tb, _ := ioutil.ReadFile(filename)\n",
    "\tb = regexp.MustCompile(\"[0-9+]\").Find(b)\n",
    "\treturn append([]byte{}, b...) // 切断对原始数据的依赖，避免内存泄漏\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "var a []*int{...}\n",
    "a[len(a)-1] = nil // 从 GC 回收最后一个元素内存\n",
    "a = a[:len(a)-1] // 从切片删除最后一个元素"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 函数、方法和接口"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]int\n",
      "[]int\n",
      "[2 4 6]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "8 <nil>"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "func twice(x []int) {\n",
    "\tfmt.Printf(\"%T\\n\", x)\n",
    "    for i := range x {\n",
    "        x[i] *= 2\n",
    "    }\n",
    "}\n",
    "\n",
    "type IntSliceHeader struct {\n",
    "    Data []int\n",
    "    Len  int\n",
    "    Cap  int\n",
    "}\n",
    "\n",
    "func twice2(x IntSliceHeader) {\n",
    "    for i := 0; i < x.Len; i++ {\n",
    "        x.Data[i] *= 2\n",
    "    }\n",
    "}\n",
    "a := []int{1, 2, 3}\n",
    "fmt.Printf(\"%T\\n\", a)\n",
    "twice(a)\n",
    "fmt.Println(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import (\n",
    "    \"sync\"\n",
    ")\n",
    "\n",
    "var total struct {\n",
    "    sync.Mutex\n",
    "    value int\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "ERROR",
     "evalue": "repl.go:6:9: not a package: \"total\" in total.Lock <*ast.SelectorExpr>",
     "output_type": "error",
     "traceback": [
      "repl.go:6:9: not a package: \"total\" in total.Lock <*ast.SelectorExpr>"
     ]
    }
   ],
   "source": [
    "\n",
    "func worker(wg *sync.WaitGroup) {\n",
    "    defer wg.Done()\n",
    "\n",
    "    for i := 0; i <= 100; i++ {\n",
    "        total.Lock()\n",
    "        total.value += i\n",
    "        total.Unlock()\n",
    "    }\n",
    "}\n",
    "\n",
    "func main() {\n",
    "    var wg sync.WaitGroup\n",
    "    wg.Add(2)\n",
    "    go worker(&wg)\n",
    "    go worker(&wg)\n",
    "    wg.Wait()\n",
    "\n",
    "    fmt.Println(total.value)\n",
    "}\n",
    "main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Go",
   "language": "go",
   "name": "gophernotes"
  },
  "language_info": {
   "codemirror_mode": "",
   "file_extension": ".go",
   "mimetype": "",
   "name": "go",
   "nbconvert_exporter": "",
   "pygments_lexer": "",
   "version": "go1.20.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
